package coap.client;

import coap.messages.*;

import java.util.Random;

public class CoAPClient{
	
	ClientSession session = null;

    private boolean failed = false;
    private Message reply = null;
    private Random r = new Random();

    public CoAPClient(String server){
		
		session = new ClientSession(server, this);
	}

    public synchronized byte[] get(String key){
        Message get = new Message(MessageType.Confirmable, MethodCodes.GET, Math.abs(r.nextInt()%65536), new byte[0]);
        byte[] token = new byte[1];
        r.nextBytes(token);
        get.addOption(new Option(OptionNumber.Token, token));
        get.addOption(new Option(OptionNumber.UriPath, key));
        session.sendMessage(get, false);

        failed = false;
        reply = null;
        while(reply==null && !failed){
            try{
                this.wait();
            }
            catch(Exception e){};
            if(failed){
                System.out.println("get failed");
                return null;
            }
            if(reply.getType() == MessageType.Acknowledgement && reply.getMessageID() == get.getMessageID()){
                //System.out.println("receive acknowledgement "+reply);
            }
            if(reply.isResponse() && reply.getOption(OptionNumber.Token).equals(get.getOption(OptionNumber.Token))){
                //System.out.println("receive reply "+reply);
                System.out.println(ResponseCodes.getString(reply.getCode()));
                return reply.getPayLoad();
            }
            reply = null;
        }
        return null;
    }

    public synchronized void put(String key, byte[]value){
        Message put = new Message(MessageType.Confirmable, MethodCodes.PUT, Math.abs(r.nextInt()%65536), value);
        byte[] token = new byte[1];
        r.nextBytes(token);
        put.addOption(new Option(OptionNumber.Token, token));
        put.addOption(new Option(OptionNumber.UriPath, key));
        session.sendMessage(put, false);

        failed = false;
        reply = null;
        while(reply==null && !failed){
            try{
                this.wait();
            }
            catch(Exception e){};
            if(failed){
                System.out.println("put failed");
            }
            if(reply.getType() == MessageType.Acknowledgement && reply.getMessageID() == put.getMessageID()){
                //System.out.println("receive acknowledgement "+reply);
            }
            if(reply.isResponse() && reply.getOption(OptionNumber.Token).equals(put.getOption(OptionNumber.Token))){
                //System.out.println("receive reply "+reply);
                System.out.println(ResponseCodes.getString(reply.getCode()));
                return;
            }
            reply = null;
        }
    }

    public synchronized void handleResponse(Message response){
        failed = false;
        reply = response;
        this.notifyAll();
    }

    public synchronized void handleAck(Message ack){
        failed = false;
        reply = ack;
        this.notifyAll();
    }

    public synchronized void failed(Message originalMessage){
        failed = true;
        this.notifyAll();
    }

    public static void main(String []args){
        String value = "songhan";
        CoAPClient client = new CoAPClient("localhost");
        client.get("haha");
        client.put("haha", value.getBytes());
        client.put("haha", value.getBytes());
        String ret = new String(client.get("haha"));
        System.out.println(ret);
        System.out.println("exit");
        System.exit(0);
    }
	
	
}
